package com.dzz.sjgl.controller;

import com.dzz.sjgl.entity.PaperInfo;
import com.dzz.sjgl.entity.UserInfo;
import com.dzz.sjgl.service.IPaperService;
import com.dzz.sjgl.service.ISentenceService;
import com.dzz.sjgl.utils.Pdf2Image;
import com.dzz.sjgl.utils.Word2Pdf;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.io.IOUtils;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.shiro.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author KRIC
 * @ClassName WordController word文档
 * @Date: 2019/3/13 11:09
 * @Description:
 */
@Controller
@ResponseBody
@RequestMapping("/word")
@PropertySource("classpath:config.properties")
public class WordController {
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    private final IPaperService paperService;
    @Value("${file.path}")
    private String path;
    private final Executor pool;
    private static final String UP_FILE_NAME = "\\upload\\";
    private final ISentenceService sentenceService;

    @Autowired
    public WordController(IPaperService paperService, Executor pool, ISentenceService sentenceService) {
        this.paperService = paperService;
        this.pool = pool;
        this.sentenceService = sentenceService;
    }

    @ApiOperation(value = "上传文件")
    @ResponseBody
    @PostMapping("/upFile")
    public String upFile(@RequestParam("file") MultipartFile[] files, String subjects, String province, String exam) {
        StringBuilder rtnMsg = new StringBuilder();
        for (MultipartFile file : files) {
            String msg = upFile1(file, subjects, province, exam);
            if (!"文件上传成功！".equals(msg)) {
                rtnMsg.append(file.getOriginalFilename()).append("、");
            }
        }
        if (StringUtils.isEmpty(rtnMsg.toString())) {
            return "文件上传成功！";
        } else {
            return rtnMsg.substring(0, rtnMsg.length() - 1) + "上传失败！";
        }
    }

    /**
     * @param file 文件
     */
    @ApiOperation(value = "上传文件")
    @ResponseBody
    @PostMapping("/upFile1")
    public String upFile1(@RequestParam("file") MultipartFile file, String subjects, String province, String exam) {
        String fileName = file.getOriginalFilename();
        if (StringUtils.isEmpty(fileName)) {
            return "上传文件为空！";
        } else if (paperService.isExist(fileName, subjects)) {
            return "该文件服务器已经存在！";
        } else if (!fileName.endsWith("doc") && !fileName.endsWith("docx")) {
            return "不支持该文件格式！";
        } else if (StringUtils.isEmpty(subjects) || StringUtils.isEmpty(province) || StringUtils.isEmpty(exam)) {
            return "请补充试卷信息！";
        }
        String pattern = "[12][90][0-9]{2}";
        Pattern r = Pattern.compile(pattern);
        Matcher m = r.matcher(fileName);
        int year;
        if (m.find()) {
            year = Integer.valueOf(m.group());
        } else {
            return "无法提取试卷年份，请检查文件名！";
        }
        InputStream in = null;
        FileOutputStream out = null;
        String wordPath = UP_FILE_NAME + subjects + "\\word\\" + fileName;
        String pdfName = fileName;
        pdfName = pdfName.replace(".docx", "x.pdf").replace("doc", "pdf");
        String pdfPath = UP_FILE_NAME + subjects + "\\pdf\\" + pdfName;

        String imgFolder = UP_FILE_NAME + subjects + "\\img\\";
        String imgPath;
        if (!(Pdf2Image.createDirectory(path + UP_FILE_NAME + subjects + "\\word\\")
                && Pdf2Image.createDirectory(path + UP_FILE_NAME + subjects + "\\pdf\\")
                && Pdf2Image.createDirectory(path + imgFolder))) {
            return "服务器异常！";
        }
//        保存word文件
        try {
//            获取上传文件存储路径
            in = file.getInputStream();
            //创建一个文件输出流
            out = new FileOutputStream(URLDecoder.decode(path + wordPath, "UTF-8"));
            //创建一个缓冲区
            byte[] buffer = new byte[1024];
            //判断输入流中的数据是否已经读完的标识
            int len;
            //循环将输入流读入到缓冲区当中，(len=in.read(buffer))>0就表示in里面还有数据
            while ((len = in.read(buffer)) > 0) {
                //使用FileOutputStream输出流将缓冲区的数据写入到指定的目录(savePath + "\\" + filename)当中
                out.write(buffer, 0, len);
            }
//            word 转 pdf
            Word2Pdf.word2Pdf(path + wordPath, path + pdfPath);
//            pdf转img
            imgPath = Pdf2Image.pdf2Image(path + pdfPath, path + imgFolder, 300, 1);
        } catch (Exception e) {
            logger.error(e.getMessage());
            return "服务器异常！";
        } finally {
            IOUtils.closeQuietly(in);
            IOUtils.closeQuietly(out);
        }


//        试卷信息保存入库
        PaperInfo paperInfo = new PaperInfo();
        paperInfo.setCreateTime(new Date());
        paperInfo.setName(fileName);
        paperInfo.setSubjects(subjects);
        UserInfo userInfo = (UserInfo) SecurityUtils.getSubject().getPrincipal();
        paperInfo.setUserId(userInfo.getId());
        paperInfo.setWordPath(wordPath);
        paperInfo.setPdfPath(pdfPath);
        paperInfo.setImgPath(imgFolder + imgPath);
        paperInfo.setStatus("0");
        paperInfo.setProvince(province);
        paperInfo.setExam(exam);
        paperInfo.setYear(year);
        paperInfo = paperService.saveAndFlush(paperInfo);
        int paperId = paperInfo.getId();
//        解析word文档
        pool.execute(() -> paperService.parsingWord(paperId));

        return "文件上传成功！";
    }

    /**
     * 导出文件
     */
    @ApiOperation(value = "导出文件")
    @ResponseBody
    @GetMapping("/export")
    public void export(HttpServletResponse response,
                       String word, Integer minCp, String province, String exam, Integer minYear, Integer maxYear) {
        XWPFDocument doc = null;
        try {
            String fileName = "词频统计.docx";
            //创建word文件
            doc = new XWPFDocument();
            //创建段落
            XWPFParagraph paragraph = doc.createParagraph();

            Map<String, Object> map = sentenceService.getCp(0, 0, word, minCp, province, exam, minYear, maxYear);
            List<Map<String, Object>> list = (List<Map<String, Object>>) map.get("content");
            for (Map<String, Object> objectMap : list) {

                int wordId = Integer.valueOf(String.valueOf(objectMap.get("id")));
                String word1 = String.valueOf(objectMap.get("word"));
                int count = Integer.valueOf(String.valueOf(objectMap.get("count")));
                //创建段落文本
                XWPFRun r1 = paragraph.createRun();
                r1.setText("单词：" + word1);
                r1.addCarriageReturn();
                XWPFRun r2 = paragraph.createRun();
                r2.setText("词频：" + count);
                r2.addCarriageReturn();
                StringBuilder sb = new StringBuilder();
                sb.append("历年试卷：");
                Map<String, Object> paper = sentenceService.getPaperByWord(0, 0, wordId, province, exam, minYear, maxYear, null);
                List<Map<String, Object>> papers = (List<Map<String, Object>>) paper.get("content");
                for (Map<String, Object> paperInfo : papers) {
//                    String year = String.valueOf(paperInfo.get("year"));
//                    String prov = String.valueOf(paperInfo.get("province"));
                    String name = String.valueOf(paperInfo.get("name"));
                    name = name.substring(0, name.lastIndexOf("."));
                    sb.append(name).append("、");
//                            .append(year.trim()).append(prov.trim())
//                            .append("【").append(name).append("】")
//                            .append("、");
                }
                XWPFRun r3 = paragraph.createRun();
                r3.setText(sb.substring(0, sb.length() - 1));
                r3.addCarriageReturn();
                r3.addCarriageReturn();
            }

            response.setContentType("application/octet-stream");
            String headStr = "attachment; filename=" + new String(fileName.getBytes(), StandardCharsets.ISO_8859_1);
            response.setHeader("Content-disposition", headStr);
            response.flushBuffer();
            doc.write(response.getOutputStream());
        } catch (Exception e) {
            logger.error(e.getMessage());
        } finally {
            IOUtils.closeQuietly(doc);
        }
    }
}
